package com.atguigu.Des;

import org.apache.commons.codec.binary.Hex;

import javax.crypto.Cipher;
import javax.crypto.KeyGenerator;
import javax.crypto.SecretKey;
import javax.crypto.spec.SecretKeySpec;
import java.security.SecureRandom;

/**
 * @author : wushikai
 * <p>
 * date : 2021-04-22
 * 密钥的包装和解包装模式是一对互逆的操作
 */
public enum WrapUtil {

    /**
     * 单例
     */
    SINGLETON;

    private static final String SECRECT = "passwrod";


    /**
     * wrap方法的作用是把原始的密钥通过某种加密算法包装为加密后的密钥，这样就可以避免在传递密钥的时候泄漏了密钥的明文。
     */
    public String wrap(String keyString) throws Exception {
        KeyGenerator keyGenerator = KeyGenerator.getInstance("AES");
        //初始化密钥生成器，指定密钥长度为128，指定随机源的种子为指定的密钥(这里是"passward")
        keyGenerator.init(128, new SecureRandom(SECRECT.getBytes()));
        SecretKey secretKey = keyGenerator.generateKey();
        SecretKeySpec secretKeySpec = new SecretKeySpec(secretKey.getEncoded(), "AES");
        Cipher cipher = Cipher.getInstance("AES");
        cipher.init(Cipher.WRAP_MODE, secretKeySpec);
        SecretKeySpec key = new SecretKeySpec(keyString.getBytes(), "AES");
        byte[] bytes = cipher.wrap(key);
        return Hex.encodeHexString(bytes);
    }


    /**
     * unwrap方法的作用是把包装(加密)后的密钥解包装为原始的密钥，得到密钥的明文。
     */
    public String unwrap(String keyString) throws Exception {
        byte[] rawKey = Hex.decodeHex(keyString.toCharArray());
        KeyGenerator keyGenerator = KeyGenerator.getInstance("AES");
        //初始化密钥生成器，指定密钥长度为128，指定随机源的种子为指定的密钥(这里是"passward")
        keyGenerator.init(128, new SecureRandom(SECRECT.getBytes()));
        SecretKey secretKey = keyGenerator.generateKey();
        SecretKeySpec secretKeySpec = new SecretKeySpec(secretKey.getEncoded(), "AES");
        Cipher cipher = Cipher.getInstance("AES");
        cipher.init(Cipher.UNWRAP_MODE, secretKeySpec);
        SecretKey key = (SecretKey) cipher.unwrap(rawKey, "AES", Cipher.SECRET_KEY);
        return new String(key.getEncoded());
    }

    public static void main(String[] args) throws Exception {
        String wrapKey = WrapUtil.SINGLETON.wrap("doge");
        System.out.println(wrapKey);
        System.out.println(WrapUtil.SINGLETON.unwrap(wrapKey));
    }
}
